package com.qyxx.platform.sysmng.process.web;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import org.springframework.beans.factory.annotation.Autowired;

import com.qyxx.platform.common.json.JsonOutput;
import com.qyxx.platform.common.module.web.CrudActionSupport;
import com.qyxx.platform.common.utils.web.struts2.Struts2Utils;
import com.qyxx.platform.sysmng.process.service.WorkflowTraceService;

/**
 * 流程部署处理类
 *
 */
@Namespace("/sys/process")
@Results({
		@Result(name = CrudActionSupport.RELOAD, location = "deploy.action", type = "redirect"),
		@Result(name = "list", location = "/WEB-INF/content/sys/workflow/process-list.jsp"),
		@Result(name = "view", location = "/WEB-INF/content/sys/workflow/process-picture.jsp")
})
public class DeployAction extends CrudActionSupport<ProcessDefinition> {

	/**
	 * long
	 */
	private static final long serialVersionUID = 5438573709611824747L;
	protected WorkflowTraceService traceService;
	protected RepositoryService repositoryService;
	protected RuntimeService runtimeService;
	@Autowired
	public void setRuntimeService(RuntimeService runtimeService) {
		this.runtimeService = runtimeService;
	}
	@Autowired
	public void setTraceService(WorkflowTraceService traceService) {
		this.traceService = traceService;
	}
	@Autowired
	public void setRepositoryService(
			RepositoryService repositoryService) {
		this.repositoryService = repositoryService;
	}
	private List<ProcessDefinition> processes;
	
	
	public List<ProcessDefinition> getProcesses() {
		return processes;
	}

	
	public void setProcesses(List<ProcessDefinition> processes) {
		this.processes = processes;
	}
	private String processInstanceId;
	private String resourceType;
	
	
	public String getResourceType() {
		return resourceType;
	}
	
	public void setResourceType(String resourceType) {
		this.resourceType = resourceType;
	}
	public String getProcessInstanceId() {
		return processInstanceId;
	}


	
	public void setProcessInstanceId(String processInstanceId) {
		this.processInstanceId = processInstanceId;
	}
	private File filedata;

	private String filedataFileName = "";
	
	private String deploymentId;

	public String getDeploymentId() {
		return deploymentId;
	}

	public void setDeploymentId(String deploymentId) {
		this.deploymentId = deploymentId;
	}

	public File getFiledata() {
		return filedata;
	}

	
	public void setFiledata(File filedata) {
		this.filedata = filedata;
	}

	
	public String getFiledataFileName() {
		return filedataFileName;
	}

	
	public void setFiledataFileName(String filedataFileName) {
		this.filedataFileName = filedataFileName;
	}
/**
 * 部署文件
 * */
	@JsonOutput
	public String deploy() throws Exception {
		//String fileName = file.getOriginalFilename();
		InputStream fileInputStream =null;
		try {
			 fileInputStream = FileUtils.openInputStream(filedata);
		
			String extension = FilenameUtils.getExtension(filedataFileName);
			if (extension.equals("zip") || extension.equals("bar")) {
				ZipInputStream zip = new ZipInputStream(
						fileInputStream);
				repositoryService.createDeployment()
						.addZipInputStream(zip).deploy();
			} else if (extension.equals("png")) {
				repositoryService.createDeployment()
						.addInputStream(filedataFileName, fileInputStream)
						.deploy();
			} else if (extension.indexOf("xml") != -1) {
				repositoryService.createDeployment()
						.addInputStream(filedataFileName, fileInputStream)
						.deploy();
			} else if (extension.equals("bpmn")) {
				/*
				 * bpmn扩展名特殊处理，转换为bpmn20.xml
				 */
				String baseName = FilenameUtils.getBaseName(filedataFileName);
				repositoryService
						.createDeployment()
						.addInputStream(baseName + ".bpmn20.xml",
								fileInputStream).deploy();
			} else {
				throw new ActivitiException(
						"no support file type of " + extension);
			}
		} catch (Exception e) {
			logger.error("error on deploy process, because of file input stream");
		}finally{
			if(fileInputStream!=null){
				fileInputStream.close();
			}
		}
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
		// return "redirect:/workflow/process-list";
	}

	/**
	 * 流程定义列表
	 * 
	 * @return
	 */
	@Override

	public String list() throws Exception {	
		processes = repositoryService.createProcessDefinitionQuery().list();
		
		return "list";
	}
	/**
	 * 输出跟踪流程信息
	 * @param processInstanceId
	 * @return
	 * @throws Exception
	 */
	@JsonOutput
	public List<Map<String, Object>> traceProcess() throws Exception {
		List<Map<String, Object>> activityInfos = traceService.traceProcess(processInstanceId);
		Struts2Utils.renderJson(activityInfos);
		return null;
	}

	/**
	 * 读取资源，通过流程ID
	 * @param resourceType			资源类型(xml|image)
	 * @param processInstanceId		流程实例ID	
	 * @param response
	 * @throws Exception
	 */
	public String loadByProcessInstance() throws Exception {
		InputStream resourceAsStream = null;
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
				.singleResult();
		ProcessDefinition singleResult = repositoryService.createProcessDefinitionQuery()
				.processDefinitionId(processInstance.getProcessDefinitionId()).singleResult();

		String resourceName = "";
		if (resourceType.equals("image")) {
			resourceName = singleResult.getDiagramResourceName();
		} else if (resourceType.equals("xml")) {
			resourceName = singleResult.getResourceName();
		}
		resourceAsStream = repositoryService.getResourceAsStream(singleResult.getDeploymentId(), resourceName);
		byte[] b = new byte[1024];
		int len = -1;
		HttpServletResponse s = Struts2Utils.getResponse();
		OutputStream out = s.getOutputStream();
		while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
			out.write(b, 0, len);
		}
		out.flush();
		return null;
	}
	@Override
	public String input() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String save() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
	/**
	 * 查看流程图
	 * @param deploymentId 流程部署ID
	 */
	@Override
	public String view() throws Exception {
		return VIEW;
	}

	/**
	 * 删除部署的流程，级联删除流程实例
	 * 
	 * @param deploymentId
	 *            流程部署ID
	 */
	@Override
	@JsonOutput
	public String delete() throws Exception {
		repositoryService.deleteDeployment(deploymentId, true);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	/**
	 * 获取流程图片
	 * @param deploymentId 流程部署ID
	 */
	public String getProcessPicture() throws Exception {
		ProcessDefinition singleResult = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
		String resourceName = singleResult.getDiagramResourceName();
		InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId,resourceName);
		HttpServletResponse response = Struts2Utils.getResponse();
		OutputStream os = response.getOutputStream();
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
			os.write(b, 0, len);
		}
		os.flush();
		return null;
	}
	@Override
	protected void prepareModel() throws Exception {
		// TODO Auto-generated method stub

	}
}
